package com.client.koshercook.server;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import com.google.appengine.api.datastore.Key;

public class ScanRecipe {

	/** Get an empty Recipes object to scan. */
	/** fills the fields of the Recipes object. */
	public ScanRecipe(Recipes rec) {
		
		IngredientsDB ingDB = IngredientsDB.getInstance();
		
		short nextInfo = 0; // 0=none. 4=ingredients. 5=instructions.

		String line;
		
		
		if (rec.getSite().equals("http://www.kipa.co.il/food/matkon/")) {
			
			// should check if id doesn't exist on web
			
			
			try {
				URL url = new URL(rec.getLink());
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(url.openStream(), "UTF-8"));
				System.out.println("scan: fetch well");

				String text;
				

				while ((line = reader.readLine()) != null) {

					if (line.contains("KotMaamar1")) // title
						rec.setRecipeName(removeXMLbrackets(line));
					if (line.contains("\u05E8\u05DB\u05D9\u05D1\u05D9\u05DD")) // rehivim
						nextInfo = 4;
					if (line.contains("\u05D4\u05D5\u05E8\u05D0\u05D5\u05EA")) // horaot
						nextInfo = 5;
					if (line.contains("\u05DE\u05EA\u05DB\u05D5\u05E0\u05D9\u05DD")
							&& line.contains("maamar-by")) // matkonim
						rec.setType(removeXMLbrackets(reader.readLine()));
					if (line.contains("maamar-by") && line.contains("http://www.kipa.co.il/community/users/"))
						rec.setUploader(removeXMLbrackets(line));
					
					if (line.contains("\u05DB\u05E9\u05E8\u05D5\u05EA")) {// kashrut
						
						if (line.contains("\u05E4\u05E8\u05D5\u05D5\u05D4")) //parve
							rec.setKosher(KosherType.PARVE);
						else if(line.contains("\u05D1\u05E9\u05E8\u05D9")) //bsari
							rec.setKosher(KosherType.MEAT);
						else if(line.contains("\u05D7\u05DC\u05D1\u05D9")) //halavi
							rec.setKosher(KosherType.DAIRY);
					}

					if (line.contains("box5")) {
						if (nextInfo == 4) {
							nextInfo = 0;
							text = reader.readLine();
							List<String> ingtxt = new ArrayList<String>();
							for(int i=0 ; i<text.length() ; i=i+500) 
								ingtxt.add(text.substring(i, Math.min(i+500,text.length())));
							rec.setIngredientsText(ingtxt);
							
							rec.setIngredients( getIngredientsFromText(text,"<br>") );
						}
						if (nextInfo == 5) {
							nextInfo = 0;
							text = reader.readLine();
							//TODO: split the text to multiple parts
							List<String> inst = new ArrayList<String>();
							for(int i=0 ; i<text.length() ; i=i+500) 
								inst.add(text.substring(i, Math.min(i+500,text.length())));
							rec.setInstructions(inst);	
						}
					}

				}
				reader.close();

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		else if (rec.getSite().equals("http://www.chef-lavan.co.il/tabid/53/RecipeID/")) {
			//~~~~~~~~~~~~~~~~~~www.chef-lavan.co.il~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			String rehivim="";			
			try {
				URL url = new URL(rec.getLink());
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(url.openStream(), "UTF-8"));
				System.out.println("scan: fetch well");

				String instructions;
				boolean hasRehivim=false;

				while ((line = reader.readLine()) != null) {

					if (line.contains("dnn_ctr911_ViewRecipes_RecipeName")) // title
						rec.setRecipeName(removeXMLbrackets(line));
					if (!hasRehivim && line.contains("dnn_ctr911_ViewRecipes_Description")){ // rehivim
						rehivim = removeXMLbracketsNotBr(line);
						List<String> ingtxt = new ArrayList<String>();
						for(int i=0 ; i<rehivim.length() ; i=i+500) 
							ingtxt.add(rehivim.substring(i, Math.min(i+500,rehivim.length())));
						rec.setIngredientsText(ingtxt);
						hasRehivim = true;
					}
					if (line.contains("dnn_ctr911_ViewRecipes_Description2")){ // horaot
						instructions = removeXMLbracketsNotBr(line);
						List<String> inst = new ArrayList<String>();
						for(int i=0 ; i<instructions.length() ; i=i+500) 
							inst.add(instructions.substring(i, Math.min(i+500,instructions.length())));
						rec.setInstructions(inst);
					}
					
					if (line.contains("_Portals__default_")) {
						line = reader.readLine();
						if(line.contains("עוגות")||line.contains("עוגת")||line.contains("עוגה")) rec.setType("עוגות");
						else if(line.contains("דגים")||line.contains("בשר")||line.contains("נתחי פרימיום")||line.contains("תבשילי קדרה")||line.contains("סטייק")||line.contains("נתחים לצלייה")||line.contains("עוף")) rec.setType("בשר ודגים");
						else if(line.contains("מרק ")) rec.setType("מרקים");
						else if(line.contains("לחמים")) rec.setType("לחמים");
						else if(line.contains("סלטים")||line.contains("סלט")) rec.setType("סלטים");
						else if(line.contains("מתוקים")||line.contains("גלידה")||line.contains("גלידת")||line.contains("שוקולד")||line.contains("מילקשייק")) rec.setType("קינוח");
						else if(line.contains("פשטידות")||line.contains("ירקות")||line.contains("מתאבנים")) rec.setType("מנה ראשונה");
						else if(line.contains("תוספות")||line.contains("פסטות")||line.contains("פסטה")) rec.setType("תוספות");
						else rec.setType("אחר");

					}
					if (line.contains("dnn_ctr911_ViewRecipes_SentByUser"))
						rec.setUploader(removeXMLbrackets(line));
					}
				reader.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				ArrayList<Key> x;
				rec.setIngredients( x=getIngredientsFromText(rehivim,"<br/>") );
					
				rec.setKosher( calcKosher(x) ); //calc the kosher
			}

		else if (rec.getSite().equals("http://www.rotev.co.il/last_video.aspx?recipe_id=")) {
			//~~~~~~~~~~~~~~~~~~www.rotev.co.il~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			String rehivim="";			
			try {
				URL url = new URL(rec.getLink());
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(url.openStream(), "UTF-8"));
				System.out.println("scan: fetch well");

				String instructions="";
				short step=0; //0=title, 1=rehivim, 2=between 1 and 3, 3=start instructions, 4=all instructions , 6=isKosher
				String temptxt="";

				while ((line = reader.readLine()) != null) {

					if (line.contains("<h1><span id=\"ctl00_ContentPlaceHolder1_FormView1_Label2\" class=\"h1\">")) {// title
						rec.setRecipeName(removeXMLbrackets(line));
						step++;
					}
					
					
					else if (step==1 && line.contains("ctl00_ContentPlaceHolder1_FormView1_Label")){ // rehivim
						temptxt = removeXMLbrackets(line);
						if(!temptxt.equals("")) rehivim = rehivim + "<br>" + removeXMLbrackets(line);	
						else {
							step=2;
							rehivim = rehivim.substring(4);
							List<String> ingtxt = new ArrayList<String>();
							for(int i=0 ; i<rehivim.length() ; i=i+500) 
								ingtxt.add(rehivim.substring(i, Math.min(i+500,rehivim.length())));
							rec.setIngredientsText(ingtxt);
						}
					}
					
					else if(step==2 && line.contains("אופן הכנה")) step=3;
					
					else if (step==3 && line.contains("ctl00_ContentPlaceHolder1_FormView1_Label")){ // horaot
						instructions = removeXMLbrackets(line);
						step=4;
					}
					
					else if (step==4){ // horaot
						if(line.contains("</span>")) {
							step=5;
							instructions += line.substring(0,line.indexOf('<'));
							List<String> inst = new ArrayList<String>();
							for(int i=0 ; i<instructions.length() ; i=i+500) 
								inst.add(instructions.substring(i, Math.min(i+500,instructions.length())));
							rec.setInstructions(inst);
						}
						else instructions += line;
						
					}

					if (step==5 && line.contains("ctl00_ContentPlaceHolder1_FormView1_HyperLink4")) { //type						
						if(line.contains("עוגות")) rec.setType("עוגות");
						else if(line.contains("מרקים")) rec.setType("מרקים");
						else if(line.contains("מאפים")) rec.setType("לחמים");
						else if(line.contains("סלטים")) rec.setType("סלטים");
						else if(line.contains("קינוחים")) rec.setType("קינוח");
						else if(line.contains("דגים")||line.contains("בשר")||line.contains("עוף")||line.contains("קדרה")) rec.setType("בשר ודגים");
						else if(line.contains("פשטידות")||line.contains("ירקות")) rec.setType("מנה ראשונה");
						else if(line.contains("גבינות")||line.contains("אורז")||line.contains("פסטות")) rec.setType("תוספות");
						else rec.setType("אחר");

					}
					
					if (step==5 && line.contains("ctl00_ContentPlaceHolder1_FormView1_HyperLink6")) {
						rec.setUploader(removeXMLbrackets(line));
						step=6;
					}
					
					if(step==6 && line.contains("ctl00_ContentPlaceHolder1_FormView1_Label")) { //is kosher?
						if(line.contains("כן")) step=7;
						else { //the recipe is not kosher = not valid!
							rec.setRecipeName(null);
							break;
						}
					}
				}
				reader.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				if(rec.getRecipeName()!=null) {
					ArrayList<Key> x;
					rec.setIngredients( x=getIngredientsFromText(rehivim,"<br>") );	
					rec.setKosher( calcKosher(x) ); //calc the kosher
				}
				
			}
		
		
		else if (rec.getSite().equals("http://www.stybel.co.il/recipe_full.php?id=")) {
			//~~~~~~~~~~~~~~~~~~www.stybel.co.il~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			String rehivim="",instructions="",name="";			
			try {
				URL url = new URL(rec.getLink());
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(url.openStream(), "windows-1255"));
				System.out.println("scan: fetch well");
				
				short step=0; //0=nothing, 1=ings, 2=inst
				boolean start = false;
				
				while ((line = reader.readLine()) != null) {
					
					if(!start) {
						if(!line.contains("javascript: window.print();")) continue;
						else {
							start = true;
							line = reader.readLine();
							line = reader.readLine();
							name = cutPreSpace(removeXMLbrackets("<>"+line));
							if(name.equals("")) break;
							rec.setRecipeName(name);
						}
					}
					
					if (line.contains("recipe_title")) {
						if (line.contains(">מצרכים<")) step=1;
						else if (line.contains(">אופן הכנה<")) step=2;
						else if (line.contains(">מאת<")) {
							rec.setUploader("stybel@"+cutPreSpace(removeXMLbrackets(reader.readLine())));
							break;
						}
					}
					else {
						if(step==1) rehivim+=cutPreSpace(line);
						else if(step==2) instructions+=cutPreSpace(line);
					}
				}
				reader.close();
				
				List<String> ingtxt = new ArrayList<String>();
				for(int i=0 ; i<rehivim.length() ; i=i+500) 
					ingtxt.add(rehivim.substring(i, Math.min(i+500,rehivim.length())));
				rec.setIngredientsText(ingtxt);
				
				List<String> inst = new ArrayList<String>();
				for(int i=0 ; i<instructions.length() ; i=i+500) 
					inst.add(instructions.substring(i, Math.min(i+500,instructions.length())));
				rec.setInstructions(inst);
					
				if(name.contains("בשר")) rec.setType("בשר ודגים");				
				else if(name.contains("לחם")||name.contains("לחמ")||name.contains("פוקצ")||name.contains("פיתה")||name.contains("פיתות")||name.contains("חלה")||name.contains("חלת")||name.contains("חלות")||name.contains("באגט")||name.contains("בייגל")) rec.setType("לחמים");
//				else if(name.contains("סלטים")) type = "סלטים";
				else if(name.contains("מאפי")||name.contains("מאפה")) rec.setType("קינוח");
				else if(name.contains("עוגת")||name.contains("פאי")) rec.setType("עוגות");
//				else if(name.contains("פשטידות")||line.contains("ירקות")) type = "מנה ראשונה";
				else if(name.contains("פיצה")||name.contains("פסטה")||name.contains("פסטות")) rec.setType("תוספות");
				else if(name.contains("מרק בצל")) rec.setType("מרקים");
				else rec.setType("אחר");

				ArrayList<Key> x;
				rec.setIngredients( x=getIngredientsFromText(rehivim,"<br />") );	
				rec.setKosher( calcKosher(x) ); //calc the kosher
				
				

			} catch (Exception e) {
				e.printStackTrace();
			}
		}


	}
	
	/** take the ingredientText and the symbol of new line, and generate a list of ings*/
	public static ArrayList<Key> getIngredientsFromText(String ingText, String splitWith) {
		IngredientsDB ingDB = IngredientsDB.getInstance();
		boolean bol;
		List<Key> x = new ArrayList<Key>();
		ArrayList<Key> ingredients = new ArrayList<Key>();
		String ings[] = ingText.split(splitWith);
		for (int i = 0; i < ings.length; i++)
			if(ings[i]!="") { 
				x=ingDB.extractIngredient(ings[i]); // extract all ingredients from the line (usually 1)
				for(Key one : x) { //remove duplicate ingredients
					bol=true;
					for(Key one2 : ingredients) {
						if(one2==one) {
							bol = false;
							break;
						}
					}
					if(bol) ingredients.add(one); 
				}
			}
		return ingredients;
	}
	
	/** calc the kosher of the recipe according to its ingredients list*/
	public static short calcKosher(List<Key> ingredients) {
		IngredientsDB ingDB = IngredientsDB.getInstance();
		short temp,kosher=KosherType.PARVE;
		for(Key k : ingredients) {
			temp = ingDB.getKosherFromKey(k);
			if(temp==KosherType.MEAT) {
				if(kosher==KosherType.DAIRY) {
					kosher=KosherType.NONE;
					break;
				}
				else kosher=KosherType.MEAT;
			}
			else if(temp==KosherType.DAIRY) {
				if(kosher==KosherType.MEAT) {
					kosher=KosherType.NONE;
					break;
				}
				else kosher=KosherType.DAIRY;
			}
			else if(temp==KosherType.NONE) {
				kosher=KosherType.NONE;
				break;
			}
			//if temp is parve than kosher isn't changed
		}
		return kosher;
	}
	
	/**remove all the <...> from the text.*/
	private String removeXMLbrackets(String text) {
		text=text+"<>";
		String bg=text;
		int i=0,sum=0;
		String end="";
		while(true) {
			  bg=bg.substring(i);
			  if((bg.indexOf('>')+sum)==text.length()-1) break; //it's over when the first '>' is the end char of the line
			  if(!bg.substring(1).contains("<")) { //for the rare case the line doesn't end with '>'
				  end=end+bg.substring(bg.indexOf('>')+1);
				  break;
			  }
			  end=end+bg.substring(bg.indexOf('>')+1, i=bg.indexOf('<',bg.indexOf('>')));
			  sum+=i;
		  }
		return end;
	}
	
	/**remove all the <...> from the text, except those containing "br".*/
	private static String removeXMLbracketsNotBr(String text) {
		String bg=text;
		int i=0,sum=0;
		String end="";
		while(true) {
			  bg=bg.substring(i);
			  if((bg.indexOf('>')+sum)==text.length()-1) break; //it's over when the first '>' is the end char of the line
			  if(!bg.substring(1).contains("<")) { //for the rare case the line doesn't end with '>'
				  end=end+bg.substring(bg.indexOf('>')+1);
				  break;
			  }
			  if(bg.substring(0, bg.indexOf('>')).contains("br")) //don't delete < > containing "br"
				  end=end+bg.substring(0, i=bg.indexOf('<',bg.indexOf('>')));
			  else end=end+bg.substring(bg.indexOf('>')+1, i=bg.indexOf('<',bg.indexOf('>')));
			  sum+=i;
		  }
		return end;
	}
	
	/** splits a string into 500 byte strings. This is for data store storage.*/
	private ArrayList<String> splitTo500Bytes(String text) {
		int len = text.length();
		ArrayList<String> a = new ArrayList<String>();
		//String[1+(len/501)];
		for(int i=0 ; i*500 < len ; i++) {
			a.add(text.substring(i*500 , Math.min((i+1)*500 , len)) );
		}
		return a;
	} 
	
	/**
	 * cut the spaces and tabs from the beginning of the line
	 */
	private static String cutPreSpace(String text) {
		int i;
		for(i=0 ; i<text.length() ; i++) {
			if(text.charAt(i)!='\t'&&text.charAt(i)!=' ') break;
		}
		return text.substring(i);
	}

}

